//
// Created by amon.huang on 2021/7/26.
//

#include "PacketQueue.h"

void PacketQueue::clear() {
    pthread_mutex_lock(&packetMutex);
    if (pPacketQueue == nullptr) {
        return;
    }
    if (!pPacketQueue->empty()) {
        while (AVPacket *pAvPacket = pPacketQueue->front()) {
            pPacketQueue->pop();
            av_packet_unref(pAvPacket);
            av_packet_free(&pAvPacket);
        }
    }
    pthread_mutex_unlock(&packetMutex);
}

AVPacket *PacketQueue::pop() {
    AVPacket *pPacket;
    pthread_mutex_lock(&packetMutex);
    while (pPacketQueue->empty()) {
        pthread_cond_wait(&packetCond, &packetMutex);
    }
    pPacket = pPacketQueue->front();
    pPacketQueue->pop();

    pthread_mutex_unlock(&packetMutex);
    return pPacket;
}

PacketQueue::PacketQueue() : packetMutex(), packetCond() {
    pthread_mutex_init(&packetMutex, nullptr);
    pthread_cond_init(&packetCond, nullptr);
    pPacketQueue = new std::queue<AVPacket *>();
}

PacketQueue::~PacketQueue() {
    if (pPacketQueue) {
        clear();
        delete pPacketQueue;
        pPacketQueue = nullptr;
        pthread_mutex_destroy(&packetMutex);
        pthread_cond_destroy(&packetCond);
    }
}

void PacketQueue::push(AVPacket *pPacket) {
    pthread_mutex_lock(&packetMutex);
    pPacketQueue->push(pPacket);
    pthread_cond_signal(&packetCond);
    pthread_mutex_unlock(&packetMutex);
}
